import { CheckUtil } from './check';

/** 正则相关包 **/
export const RegExpUtil = {
  /**
   * 获取正则表达式：指定位数整数
   * @param {includeMinus:是否包含负数, includeZero:是否包含零, minInt:整数最小位, maxInt:整数最大位}
   * @returns {RegExp}
   */
  intRE({ includeMinus = false, includeZero = true, minInt, maxInt }) {
    const prefix = includeMinus ? '-?' : '';
    const isZero = includeZero ? '0|' : '';
    if (CheckUtil.isInt(minInt) || CheckUtil.isInt(maxInt)) {
      maxInt = maxInt > minInt ? maxInt : minInt;
      return new RegExp('^' + prefix + '(' + isZero + '[1-9]{' + minInt + ',' + maxInt + '})$');
    }

    return new RegExp('^' + prefix + '(' + isZero + '[1-9]\\d*)$');
  },

  /**
   * 获取正则表达式：指定位数浮点数
   * @param {includeMinus:是否包含负数, includeZero:是否包含零, minInt:整数最小位, maxInt:整数最大位, minFloat:小数最小位:, maxFloat:小数最大位}
   * @returns {RegExp}
   */
  floatRE({ includeMinus = false, includeZero = true, minInt, maxInt, minFloat, maxFloat }) {
    const prefix = includeMinus ? '-?' : '';
    let intPath, floatPath, re;

    if (CheckUtil.isInt(minInt) || CheckUtil.isInt(maxInt) || CheckUtil.isInt(minFloat) || CheckUtil.isInt(maxFloat)) {
      maxInt = maxInt > minInt ? maxInt : minInt;
      maxFloat = maxFloat > minFloat ? maxFloat : minFloat;

      intPath = '[1-9]\\d{' + minInt + ',' + maxInt + '}';
      floatPath = '(\\.\\d{' + minFloat + ',' + maxFloat + '})' + (includeZero ? '?' : '');
      re = new RegExp('(^' + prefix + '0' + floatPath + '$)' + '|(^' + prefix + intPath + floatPath + '$)');
    } else {
      intPath = '[1-9]\\d*';
      floatPath = '(\\.\\d+)' + (includeZero ? '?' : '');
      re = new RegExp('(^' + prefix + '0' + floatPath + '$)' + '|(^' + prefix + intPath + '(\\.\\d+)?' + '$)');
    }

    return re;
  },

  /** 获取正则表达式：中文字符 */
  chineseRE() {
    return /^[\u4e00-\u9fa5]*$/;
  },

  /** 获取正则表达式：英文和数字 */
  englishAndNumberRE() {
    return /^[A-Za-z0-9]+$/;
  },

  /** 获取正则表达式：邮箱 */
  emailRE() {
    return /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/;
  },

  /** 获取正则表达式：域名 */
  domainRE() {
    return /[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+\.?/;
  },

  /** 获取正则表达式：URL */
  urlRE() {
    return /[a-zA-z]+:\/\/[^\s]*/;
  },

  /** 获取正则表达式：手机号码 */
  cellphoneNumberRE() {
    return /^1[3-9]\d{9}$/;
  },

  /** 获取正则表达式：电话号码 */
  telephoneNumberRE() {
    return /^((\d{3,4}-)|\d{3,4}-)?\d{7,8}$/;
  },

  /** 获取正则表达式：国内电话号码 */
  telephoneNumberCnRE() {
    return /\d{3}-\d{8}|\d{4}-\d{7}/;
  },

  /** 获取正则表达式：18位身份证 */
  identityCardRE() {
    return /(^\d{18}$)|(^\d{17}(\d|X|x)$)/;
  },

  /** 获取正则表达式：qq */
  qqRE() {
    return /[1-9][0-9]{4,}/;
  },

  /** 获取正则表达式：国内邮政编码 */
  postalCodeCnRE() {
    return /[1-9]\d{5}(?!\d)/;
  },

  /** 获取正则表达式：ip地址（v4） */
  ipv4RE() {
    return /((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})(\.((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})){3}/;
  },

  /**
   * 检测文件类型，
   * @param str <文件名>
   * @param suf <期望的文件类型>, 'png|jpeg|jpg'
   * @returns {boolean}
   */
  isTypeFile(str, suf) {
    const strRegex = '(.' + suf.replace(/\|(.*?)/g, '|.$1') + ')$';
    const re = new RegExp(strRegex);
    return re.test(str.toLocaleString().toLowerCase());
  },

  isTxtFile(str) {
    return this.isTypeFile(str, 'txt|text');
  },

  isImageFile(str) {
    return this.isTypeFile(str, 'png|jpg|jpeg|bmp|gif');
  },

  isPdfFile(str) {
    return this.isTypeFile(str, 'pdf');
  },

  isExcelFile(str) {
    return this.isTypeFile(str, 'xls|xlsx');
  },

  isWordFile(str) {
    return this.isTypeFile(str, 'doc|docx');
  },

  isPptFile(str) {
    return this.isTypeFile(str, 'ppt|pptx');
  },

  isZipFile(str) {
    return this.isTypeFile(str, 'rar|zip|7z');
  },

  isVideoFile(str) {
    return this.isTypeFile(str, 'mp4|m2v|mkv|rmvb|wmv|avi|flv|mov|m4v');
  },

  isRadioFile(str) {
    return this.isTypeFile(str, 'mp3|wav');
  },

  isTel(str) {
    return this.cellphoneNumberRE().test(str);
  },

  isQQ(str) {
    return this.qqRE().test(str);
  },

  // 正整数，包含0
  isInt(str) {
    return this.intRE({}).test(str);
  },

  // 正整数，不包含0
  isPositiveInt(str) {
    return this.intRE({ includeZero: false }).test(str);
  },
};
